package org.cid54.bukkit.command;

import org.cid54.bukkit.command.util.PlayerCommand;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.event.player.PlayerChatEvent;
import org.cid54.bukkit.Cid54PlayerListener;

/**
 *
 * @author Cid54
 */
public class ConnectCommand implements PlayerCommand {

    public boolean execute(String command, PlayerChatEvent event, Cid54PlayerListener listener) {

        Location source = Cid54PlayerListener.cloneLocation(event.getPlayer().getLocation());
        String direction = command.split(" ")[1].toLowerCase();
        int distance = Integer.parseInt(command.split(" ")[2]);

        if (direction.equals("x")) {

            if (distance < 0) {

                source.setX(source.getX() + distance);

                distance *= -1;

            }

            for (int i = 0; i < distance; i++) {

                this.makeSolidCoreX(event.getPlayer().getWorld(), source);
                this.makeSolidCoreX(event.getPlayer().getWorld(), source);
                this.makeCoreSurroundingX(event.getPlayer().getWorld(), source);
                this.makeCoreSurroundingX(event.getPlayer().getWorld(), source);
                this.makeHollowCoreX(event.getPlayer().getWorld(), source);
                this.makeHollowCoreX(event.getPlayer().getWorld(), source);
                if (i % 4 == 0) {
                    this.makeTracksX(event.getPlayer().getWorld(), source, Material.RAILS);
                } else if (i % 4 == 1 || i % 4 == 3) {
                    this.makeTracksX(event.getPlayer().getWorld(), source, Material.DETECTOR_RAIL);
                } else {
                    this.makeTracksX(event.getPlayer().getWorld(), source, Material.POWERED_RAIL);
                }

                if (i % 8 == 2) {
                    this.placeTorchesX(event.getPlayer().getWorld(), source);
                }

                source.setX(source.getX() + 1D);

            }
        } else if (direction.equals("z")) {

            if (distance < 0) {

                source.setZ(source.getZ() + distance);

                distance *= -1;

            }

            for (int i = 0; i < distance; i++) {

                this.makeSolidCoreZ(event.getPlayer().getWorld(), source);
                this.makeSolidCoreZ(event.getPlayer().getWorld(), source);
                this.makeCoreSurroundingZ(event.getPlayer().getWorld(), source);
                this.makeCoreSurroundingZ(event.getPlayer().getWorld(), source);
                this.makeHollowCoreZ(event.getPlayer().getWorld(), source);
                this.makeHollowCoreZ(event.getPlayer().getWorld(), source);
                if (i % 4 == 0) {
                    this.makeTracksZ(event.getPlayer().getWorld(), source, Material.RAILS);
                } else if (i % 4 == 1 || i % 4 == 3) {
                    this.makeTracksZ(event.getPlayer().getWorld(), source, Material.DETECTOR_RAIL);
                } else {
                    this.makeTracksZ(event.getPlayer().getWorld(), source, Material.POWERED_RAIL);
                }

                if (i % 8 == 2) {
                    this.placeTorchesZ(event.getPlayer().getWorld(), source);
                }

                source.setZ(source.getZ() + 1D);

            }
            return true;
        }
        return false;

    }

    public String getCommand() {
        return "connect";
    }

    public String getHelpText() {
        return "connect x|z distance";
    }

    private boolean checkBlock(Block b) {

        if (!b.getType().equals(Material.AIR)) {
            b.setType(Material.GLASS);
            return true;
        }
        return false;
    }

    private void makeHollowCoreX(World w, Location loc) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        l.setY(l.getY() - 1D);

        //main core
        w.getBlockAt(l).setType(Material.STONE);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.AIR);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.STONE);

        l.setY(l.getY() + 1D);
        l.setZ(loc.getZ());

        w.getBlockAt(l).setType(Material.AIR);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.AIR);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.AIR);

        l.setY(l.getY() + 1D);
        l.setZ(loc.getZ());

        w.getBlockAt(l).setType(Material.AIR);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.AIR);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.AIR);

    }

    private void makeHollowCoreZ(World w, Location loc) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        l.setY(l.getY() - 1D);

        //main core
        w.getBlockAt(l).setType(Material.STONE);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.AIR);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.STONE);

        l.setY(l.getY() + 1D);
        l.setX(loc.getX());

        w.getBlockAt(l).setType(Material.AIR);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.AIR);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.AIR);

        l.setY(l.getY() + 1D);
        l.setX(loc.getX());

        w.getBlockAt(l).setType(Material.AIR);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.AIR);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.AIR);

    }

    private void makeTracksX(World w, Location loc, Material mat) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        //main core
        w.getBlockAt(l).setType(mat);
        l.setZ(l.getZ() + 2D);
        w.getBlockAt(l).setType(mat);

    }

    private void makeTracksZ(World w, Location loc, Material mat) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        //main core
        w.getBlockAt(l).setType(mat);
        l.setX(l.getX() + 2D);
        w.getBlockAt(l).setType(mat);

    }

    private boolean checkForLightStone(World w, Location l) {

        l = Cid54PlayerListener.cloneLocation(l);

        l.setY(l.getY() + 2D);

        return w.getBlockAt(l).getType().equals(Material.GLOWSTONE);

    }

    private void placeTorchesX(World w, Location loc) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        l.setZ(l.getZ() + 1D);

        if (!this.checkForLightStone(w, l)) {
            l.setY(l.getY() - 1D);
            w.getBlockAt(l).setType(Material.STONE);
            l.setY(l.getY() + 1D);
            w.getBlockAt(l).setType(Material.TORCH);
        }
    }

    private void placeTorchesZ(World w, Location loc) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        l.setX(l.getX() + 1D);

        if (!this.checkForLightStone(w, l)) {
            l.setY(l.getY() - 1D);
            w.getBlockAt(l).setType(Material.STONE);
            l.setY(l.getY() + 1D);
            w.getBlockAt(l).setType(Material.TORCH);
        }
    }

    private void makeSolidCoreX(World w, Location loc) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        l.setY(l.getY() - 1D);

        //main core
        w.getBlockAt(l).setType(Material.STONE);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.STONE);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.STONE);

        l.setY(l.getY() + 1D);
        l.setZ(loc.getZ());

        w.getBlockAt(l).setType(Material.STONE);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.STONE);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.STONE);

        l.setY(l.getY() + 1D);
        l.setZ(loc.getZ());

        w.getBlockAt(l).setType(Material.STONE);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.STONE);
        l.setZ(l.getZ() + 1D);
        w.getBlockAt(l).setType(Material.STONE);

    }

    private void makeSolidCoreZ(World w, Location loc) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        l.setY(l.getY() - 1D);

        //main core
        w.getBlockAt(l).setType(Material.STONE);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.STONE);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.STONE);

        l.setY(l.getY() + 1D);
        l.setX(loc.getX());

        w.getBlockAt(l).setType(Material.STONE);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.STONE);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.STONE);

        l.setY(l.getY() + 1D);
        l.setX(loc.getX());

        w.getBlockAt(l).setType(Material.STONE);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.STONE);
        l.setX(l.getX() + 1D);
        w.getBlockAt(l).setType(Material.STONE);

    }

    private void makeCoreSurroundingX(World w, Location loc) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        l.setZ(l.getZ() - 1D);

        this.checkBlock(w.getBlockAt(l));
        l.setY(l.getY() + 1D);
        this.checkBlock(w.getBlockAt(l));
        l.setY(l.getY() + 1D);
        this.checkBlock(w.getBlockAt(l));

        l.setZ(l.getZ() + 1D);
        this.checkBlock(w.getBlockAt(l));
        l.setZ(l.getZ() + 1D);
        if (this.checkBlock(w.getBlockAt(l))) {
            w.getBlockAt(l).setType(Material.GLOWSTONE);
        }
        l.setZ(l.getZ() + 1D);
        this.checkBlock(w.getBlockAt(l));
        l.setZ(l.getZ() + 1D);
        this.checkBlock(w.getBlockAt(l));

        l.setY(l.getY() - 1D);
        this.checkBlock(w.getBlockAt(l));
        l.setY(l.getY() - 1D);
        this.checkBlock(w.getBlockAt(l));

    }

    private void makeCoreSurroundingZ(World w, Location loc) {

        Location l = Cid54PlayerListener.cloneLocation(loc);

        l.setX(l.getX() - 1D);

        this.checkBlock(w.getBlockAt(l));
        l.setY(l.getY() + 1D);
        this.checkBlock(w.getBlockAt(l));
        l.setY(l.getY() + 1D);
        this.checkBlock(w.getBlockAt(l));

        l.setX(l.getX() + 1D);
        this.checkBlock(w.getBlockAt(l));
        l.setX(l.getX() + 1D);
        if (this.checkBlock(w.getBlockAt(l))) {
            w.getBlockAt(l).setType(Material.GLOWSTONE);
        }
        l.setX(l.getX() + 1D);
        this.checkBlock(w.getBlockAt(l));
        l.setX(l.getX() + 1D);
        this.checkBlock(w.getBlockAt(l));

        l.setY(l.getY() - 1D);
        this.checkBlock(w.getBlockAt(l));
        l.setY(l.getY() - 1D);
        this.checkBlock(w.getBlockAt(l));

    }
}
